package com.alangyun.remind.repository;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.springframework.web.multipart.MultipartFile;

import com.alangyun.remind.error.MindException;
import com.alangyun.remind.repository.mapping.DatabaseFile;
import com.alangyun.remind.repository.mapping.DatasetFile;
import com.alangyun.remind.repository.mapping.DatasetHistory;
import com.alangyun.remind.utils.Utility;

public final class StoreEngine {
	/** 数据路径 * */
	private static StorePath path = null;
	/** 数据库 * */
	private static DatabaseFile db;

	public static void init(String rootPath) throws IOException {
		path = StorePath.create(rootPath);
		db = DatabaseFile.loadDatabase(path.getDbPath());
	}

	public synchronized static String saveDataset(IDataset data, String origin) throws IOException {
		return db.saveDataset(path.getDbPath(), origin, data);
	}

	public synchronized static <T> T openDataset(Class<? extends IDataset> rootClazz, Class<?>... childClasses)
			throws IOException {
		return db.openDataset(rootClazz, path.getDbPath(), childClasses);
	}
	
	public List<DatasetFile> getDbCollections(){
		return new ArrayList<DatasetFile>(db.getDatasets().values());
	}

	public static File saveFile(MultipartFile file) throws IOException {
		NameAndExt nae = new NameAndExt(file.getOriginalFilename());

		File ret = new File(path.getUploadPath(), guid() + nae.ext);
		file.transferTo(ret);

		return ret;
	}
	
	private static String guid() {
		UUID uuid = UUID.randomUUID();
		return uuid.toString().toLowerCase().replaceAll("-", "");
	}
	
	public static List<ImportInfo> getHistory(){
		List<ImportInfo> ret = new ArrayList<ImportInfo>();
		
		Collection<DatasetFile> list = db.getDatasets().values();
		if(list!=null&&list.size()>0) {
			for(DatasetFile ds: list) {
				ImportInfo item= ImportInfo.create(ds.getKey(), ds.getLastModify());
				if(ds.getHistories()!=null&&ds.getHistories().getFilenames()!=null
						&&ds.getHistories().getFilenames().size()>0) {
					for(DatasetHistory.HistoryFile his: ds.getHistories().getFilenames()) {
						item.getHistories().add(ImportInfo.create(his.getPrimeName(), his.getDate()));
					}
				}
				ret.add(item);
			}
		}
		return ret;
	}
	
	public static class ImportInfo {

		private String name;
		private String lastDate;
		private List<ImportInfo> histories;
		
		public static ImportInfo create(String name, Date date) {
			ImportInfo ret = new ImportInfo();
			ret.name = name;
			ret.lastDate = Utility.dateToStr(date, Utility.DATETIME_FORMAT);
			ret.histories = new ArrayList<>();
			return ret;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public String getLastDate() {
			return lastDate;
		}

		public void setLastDate(String lastDate) {
			this.lastDate = lastDate;
		}

		public List<ImportInfo> getHistories() {
			return histories;
		}

		public void setHistories(List<ImportInfo> histories) {
			this.histories = histories;
		}
	}


	public static class NameAndExt {
		private String name;
		private String ext;

		private NameAndExt(String fileName) {
			int i = fileName.lastIndexOf('.');
			if (i == -1)
				name = fileName;
			else {
				name = fileName.substring(0, i);
				ext = fileName.substring(i);
			}
		}

		public String getName() {
			return name;
		}

		public String getExt() {
			return ext;
		}

	}

	public static class StorePath {
		private static final String BUCKET_DB = "collection";
		private static final String BUCKET_FILE = "file";

		private File dbPath = null;
		private File uploadPath = null;

		private StorePath() {
			dbPath = null;
			uploadPath = null;
		}

		public File getDbPath() {
			return dbPath;
		}

		public File getUploadPath() {
			return uploadPath;
		}

		public static StorePath create(String dataRootPath) {

			StorePath ret = new StorePath();

			File rootPath = new File(dataRootPath);
			if (!rootPath.exists()) {
				if (!rootPath.mkdirs())
					throw new MindException("创建目录[" + rootPath.getAbsolutePath() + "]失败");
			}
			// 创建数据目录
			ret.dbPath = new File(rootPath, BUCKET_DB);
			if (!ret.dbPath.exists()) {
				if (!ret.dbPath.mkdirs())
					throw new MindException("创建目录[" + ret.dbPath.getAbsolutePath() + "]失败");
			}
			// 创建上传目录
			ret.uploadPath = new File(rootPath, BUCKET_FILE);
			if (!ret.uploadPath.exists()) {
				if (!ret.uploadPath.mkdirs())
					throw new MindException("创建目录[" + ret.uploadPath.getAbsolutePath() + "]失败");
			}

			return ret;
		}

	}

}
